/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ora_ttc8_tti_rxd.c                                 */
/*  NOTE      =                                                    */
/*  DATE      = 2014/10/21 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>

#include "frcomm.h"
#include "frstr.h"
#include "frmem.h"
#include "frlog.h"

#include "conntrack.h"
#include "frct_comm.h"

#include "../../ora_core.h"
#include "../../comm/ora_comm.h"
#include "../../comm/ora_util.h"
#include "../ora_mar_engine.h"
#include "ora_ttc8_tti_rxd.h"


/*******************************************************************************
*  FUNC     :  对应于 void unmarshalBVC(int paramInt) 方法
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_st_sess                           (Oracle私有的session)
*           :  *p_st_ora_packet                     (Oracle数据包)
*           :  i_bit_num                            (bit个数)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_tti_rxd_unmarshalBVC(Conntrack *p_st_conn
                                , L7session_ora *p_st_sess
                                , L7_ora_packet *p_st_ora_packet
                                , int i_bit_num)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    short s_tmp = 0;
    int i_i = 0;
    int k_loop = 0;
    int n_loop = 0;
    char c_m = 0;

    if (i_bit_num > BITNSLOTS(APM_ORA_MAX_COLUMNS))
        goto error;

    p_st_curr_sess->i_bvc_num = 0;
    for (k_loop = 0; k_loop < i_bit_num; k_loop++)
    {
        if (ora_mar_unmarshalUB1(p_st_ora_packet, &s_tmp) != FR_SUCC) // m
            goto error;
        c_m = (char) (s_tmp & 0xFF);
        for (n_loop = 0; n_loop < 8; n_loop++)
        {
            if ((c_m & 1 << n_loop) != 0)
            {
                BITSET(p_st_curr_sess->arr_columns_bit, k_loop * 8 + n_loop);
                p_st_curr_sess->i_bvc_num++;
                i_i++;
            }
            else
                BITCLEAR(p_st_curr_sess->arr_columns_bit, k_loop * 8 + n_loop);
        }
    }

    p_st_curr_sess->i_bvc_found = FR_YES;

    return FR_SUCC;
error:
    return FR_FAIL;
}

/*******************************************************************************
*  FUNC     :  根据bitvector设置columns bit
*  ARGS     :  *p_st_conn                           (ct信息)
*           :  *p_bitvector                         (bitvector内容)
*           :  i_bitvector_len                      (bitvector长度)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_ttc8_tti_rxd_readBitVector(Conntrack *p_st_conn
                                , char *p_bitvector
                                , int i_bitvector_len)
{
    L7_session *p_st_session = frct_get_session(p_st_conn);
    L7session_ora_private *p_st_session_private = (L7session_ora_private *) frct_get_session_private(p_st_session);
    L7_ora_curr_session *p_st_curr_sess = p_st_session_private->p_st_curr_sess;
    int i_i = 0;
    int k_loop = 0;
    int n_loop = 0;
    char c_m = 0;

    // 超过1000个最大columns的值时返回错误
    if (i_bitvector_len > BITNSLOTS(APM_ORA_MAX_COLUMNS))
        return FR_FAIL;

    if (p_bitvector == NULL || i_bitvector_len == 0)
        p_st_curr_sess->i_bvc_found = FR_NO;
    else
    {
        for (k_loop = 0; k_loop < i_bitvector_len; k_loop++)
        {
            c_m = p_bitvector[k_loop];
            for (n_loop = 0; n_loop < 8; n_loop++)
            {
                if ((c_m & 1 << n_loop) != 0)
                {
                    ORA_PRINT_DBG("set column bit %d to 1\n", k_loop * 8 + n_loop);
                    BITSET(p_st_curr_sess->arr_columns_bit, k_loop * 8 + n_loop);
                    p_st_curr_sess->i_bvc_num++;
                    i_i++;
                }
                else
                {
                    BITCLEAR(p_st_curr_sess->arr_columns_bit, k_loop * 8 + n_loop);
                }
            }
        }
        p_st_curr_sess->i_bvc_found = FR_YES;
    }
    ORA_PRINT_DBG("p_st_curr_sess->i_bvc_num:[%d]\n", p_st_curr_sess->i_bvc_num);

    return FR_SUCC;
}
